package falstad;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.KeyListener;
import java.util.Observable;
import java.util.Observer;

import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.JTextArea;

public class GUIManager extends JFrame implements Observer{
	Maze maze  = new Maze();
	
	RobotDriver driver;
	Robot robot = new StandardRobot(maze);
	//organize this later
	Container parent ;
	
	
	
	KeyListener kl;
	
	JProgressBar batteryBar = new JProgressBar();
	
	JMenuBar menuBar = new JMenuBar();
	JPanel mainPanel = new JPanel();
	JPanel subPanel = new JPanel();
	JPanel tertiaryPanel = new JPanel();
	private JPanel sliderPanel = new JPanel();
	
	JButton interruptButton = new JButton(Constants.BUTTONNAME_BUILD_INTERRUPT);
	JButton terminateButton = new JButton(Constants.BUTTONNAME_TERMINATE);
	JButton continueButton = new JButton(Constants.BUTTONNAME_CONTINUEPLAYING);
	JButton playButton = new JButton(Constants.BUTTONNAME_PLAY);
	JButton readFile = new JButton(Constants.BUTTONNAME_READFILE);
	JButton startRobotButton = new JButton(Constants.BUTTONNAME_STARTROBOT);
	
	JButton returnToTitleScreenButton = new JButton(Constants.BUTTONNAME_RETURNTOTITLESCREEN);
	JSlider skillSlider = new JSlider(JSlider.HORIZONTAL, Constants.SKILL_MIN, Constants.SKILL_MAX, Constants.SKILL_INIT);

	//Radio Buttons
	JRadioButton wallFollowerButton = new JRadioButton(Constants.BUTTONNAME_WALLFOLLOWER);
	JRadioButton wizardButton = new JRadioButton(Constants.BUTTONNAME_WIZARD);
	JRadioButton gamblerButton = new JRadioButton(Constants.BUTTONNAME_GAMBLER);
	JRadioButton curiousGamblerButton = new JRadioButton(Constants.BUTTONNAME_CURIOUSGAMBLER);
	JRadioButton manualButton = new JRadioButton(Constants.BUTTONNAME_MANUAL);
	
	ButtonGroup driverChoices;
	
	JFileChooser fc = new JFileChooser();
	JPanel batteryBarPanel = new JPanel();	

	public GUIManager(Maze maze)
	{
		this.maze = maze ;
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(new BoxLayout(getContentPane(),BoxLayout.PAGE_AXIS));
		setSize(400,580);
		init();
	}
	
	private void initMenuBar()
	{
		MenuActionListener ml = new MenuActionListener(getContentPane(), maze, fc);
		JMenu menu = new JMenu("FILE");
		JMenuItem open = new JMenuItem("OPEN");
		JMenuItem save = new JMenuItem("SAVE");
		save.addActionListener(ml);
		open.addActionListener(ml);
	//	menu.addActionListener(ml);
		menu.add(open);
		menu.add(save);
		menuBar.add(menu);
		add(menuBar);
		
	}
	
	
	private void initBatteryLevelBarPanel()
	{
		batteryBarPanel = new JPanel();
		JProgressBar progressBar = new JProgressBar(0, 2500);
		BatteryBarWorker bbw = new BatteryBarWorker(this, progressBar, robot.getCurrentBatteryLevel());
		bbw.execute();
		progressBar.setValue(0);
		progressBar.setStringPainted(true);
		batteryBarPanel.add(progressBar);
		add(batteryBarPanel);
	}
	
	
	private void initRobotDriverButtons()
	{
		RobotChoiceActionListener rcal = new RobotChoiceActionListener(this, robot, driver, maze);
		
		startRobotButton.addActionListener(rcal);
		
		ButtonGroup driverChoices = new ButtonGroup();
		
		//Adding action Listeners to the Buttons
		manualButton.addActionListener(rcal);
		wallFollowerButton.addActionListener(rcal);
		wizardButton.addActionListener(rcal);
		curiousGamblerButton.addActionListener(rcal);
		gamblerButton.addActionListener(rcal);
		
		//Adding the buttons to the button group
		driverChoices.add(manualButton);
		driverChoices.add(wallFollowerButton);
		driverChoices.add(wizardButton);
		driverChoices.add(curiousGamblerButton);
		driverChoices.add(gamblerButton);
		
		//robot = new StandardRobot(maze);
		//driver = new manualDriver(robot);
		
		//robot = new WallFollowerRobot(maze);
		//driver = new WallFollowerDriver(robot);
	}
	
	private void initButtons()
	{
		SimpleActionListener al = new SimpleActionListener(this, maze, skillSlider);
		interruptButton.addActionListener(al);
		terminateButton.addActionListener(al);
		continueButton.addActionListener(al);
		playButton.addActionListener(al);
		returnToTitleScreenButton.addActionListener(al);
		
		
		skillSlider.setMajorTickSpacing(3);
		skillSlider.setMinorTickSpacing(1);
		skillSlider.setPaintTicks(true);
		skillSlider.setPaintLabels(true);
	}
	
	private void init()
	{
		initMenuBar();
		initButtons();
		initRobotDriverButtons();
		maze.state.addObserver(this);
		maze.getPanel().setPreferredSize(new Dimension(400,400));
		add(maze.getPanel());
		//kl = new SimpleKeyListener(this, maze) ;
		//addKeyListener(kl) ;
		
		setVisible(true) ;	
		setFocusable(true) ;
		
	}
	
	
	private void manageButtons()
	{
		remove(mainPanel);
		remove(subPanel);
		remove(tertiaryPanel);
		remove(skillSlider);
		//remove(batteryBarPanel);
		mainPanel = new JPanel();
		subPanel = new JPanel();
		tertiaryPanel = new JPanel();
		sliderPanel = new JPanel();
		switch(maze.state.getState())
		{
		case Constants.STATE_TITLE:
		{
			add(skillSlider);
			sliderPanel.setVisible(true);
			mainPanel = makeButtonPanel(playButton);
			subPanel = makeRadioButtonPanel(manualButton ,wallFollowerButton, wizardButton);
			tertiaryPanel = makeRadioButtonPanel(curiousGamblerButton, gamblerButton);
			//slider and play buttons
			break;
		}
		case Constants.STATE_FINISH:
		{
			mainPanel = makeButtonPanel(continueButton, terminateButton);
			break;
		}
		case Constants.STATE_GENERATING:
		{
			mainPanel = makeButtonPanel(interruptButton);
			break;
		}
		case Constants.STATE_PLAY:
		{
			mainPanel = makeButtonPanel(returnToTitleScreenButton, startRobotButton);
			//initBatteryLevelBarPanel();
			break;
		}
		}
		add(mainPanel);
		add(subPanel);
		add(tertiaryPanel);
	}

	@Override
	public void update(Observable arg0, Object arg1) {
//		System.out.println("The State was changed");
		manageButtons();
		validate();
		repaint();
		
	}
	
	private void startRobot()
	{
		try {
			driver.drive2Exit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private JPanel makeRadioButtonPanel(JRadioButton b1, JRadioButton b2, JRadioButton b3)
	{
		JPanel buttonMenu =  new JPanel();
		buttonMenu.setLayout(new BoxLayout(buttonMenu,BoxLayout.X_AXIS));
		buttonMenu.add(b1);
		buttonMenu.add(b2);
		buttonMenu.add(b3);
		buttonMenu.setVisible(true);
		return buttonMenu;
		
	}
	
	private JPanel makeRadioButtonPanel(JRadioButton b1, JRadioButton b2)
	{
		JPanel buttonMenu =  new JPanel();
		buttonMenu.setLayout(new BoxLayout(buttonMenu,BoxLayout.X_AXIS));
		buttonMenu.add(b1);
		buttonMenu.add(b2);
		buttonMenu.setVisible(true);
		return buttonMenu;
		
	}
	
	private JPanel makeButtonPanel(JButton b1, JButton b2, JButton b3)
	{
		JPanel buttonMenu =  new JPanel();
		buttonMenu.setLayout(new BoxLayout(buttonMenu,BoxLayout.X_AXIS));
		buttonMenu.add(b1);
		buttonMenu.add(b2);
		buttonMenu.add(b3);
		buttonMenu.setVisible(true);
		return buttonMenu;
		
	}
	
	private JPanel makeButtonPanel(JButton b1, JButton b2)
	{
		JPanel buttonMenu =  new JPanel();
		buttonMenu.setLayout(new BoxLayout(buttonMenu,BoxLayout.X_AXIS));
		buttonMenu.setPreferredSize( new Dimension(this.getWidth(),100));
		b1.setPreferredSize(new Dimension(this.getWidth()/2, 100));
		b2.setPreferredSize(new Dimension(this.getWidth()/2, 100));
		buttonMenu.add(b1);
		buttonMenu.add(b2);
		buttonMenu.setVisible(true);
		return buttonMenu;
	}
	
	private JPanel makeButtonPanel(JButton b1)
	{
		JPanel buttonMenu =  new JPanel();
		buttonMenu.setLayout(new BoxLayout(buttonMenu,BoxLayout.X_AXIS));
		b1.setPreferredSize(new Dimension(this.getWidth()/2, 100));
		buttonMenu.add(b1);
		buttonMenu.setVisible(true);
		return buttonMenu;
		
	}
	
	
}
